<template>
  <div class="ace-container">
    <!-- 官方文档中使用id，这里禁止使用，在后期打包后容易出现问题，使用 ref 或者 DOM 就行 -->
    <div ref="ace" class="ace-editor"></div>
  </div>
</template>

<script>
import ace from 'ace-builds'

import 'ace-builds/src-min-noconflict/theme-sqlserver'
// 设置主题
import themeSqlServerUrl from 'ace-builds/src-min-noconflict/theme-sqlserver.js?url'
ace.config.setModuleUrl('ace/theme/sqlserver', themeSqlServerUrl)

// 添加javascript语言模块
import javascriptModeUrl from 'ace-builds/src-min-noconflict/mode-javascript?url'
ace.config.setModuleUrl('ace/mode/javascript', javascriptModeUrl)

// 添加json语言模块
import jsonModeUrl from 'ace-builds/src-min-noconflict/mode-json?url'
ace.config.setModuleUrl('ace/mode/json', jsonModeUrl)

// 添加css语言模块
import cssModeUrl from 'ace-builds/src-min-noconflict/mode-css?url'
ace.config.setModuleUrl('ace/mode/css', cssModeUrl)

// 添加lua语言模块
import luaModeUrl from 'ace-builds/src-min-noconflict/mode-lua?url'
ace.config.setModuleUrl('ace/mode/lua', luaModeUrl)

// 用于完成语法检查、代码提示、自动补全等代码编辑功能
import workBaseUrl from 'ace-builds/src-min-noconflict/worker-base?url'
ace.config.setModuleUrl('ace/mode/base', workBaseUrl)

// 支持javascript
import javascriptWorkerUrl from 'ace-builds/src-min-noconflict/worker-javascript?url'
ace.config.setModuleUrl('ace/mode/javascript_worker', javascriptWorkerUrl)

// 支持json
import jsonWorkerUrl from 'ace-builds/src-min-noconflict/worker-json?url'
ace.config.setModuleUrl('ace/mode/json_worker', jsonWorkerUrl)

// 支持css
import cssWorkerUrl from 'ace-builds/src-min-noconflict/worker-css?url'
ace.config.setModuleUrl('ace/mode/css_worker', cssWorkerUrl)

// 支持lua
import luaWorkerUrl from 'ace-builds/src-min-noconflict/worker-lua?url'
ace.config.setModuleUrl('ace/mode/lua_worker', luaWorkerUrl)

// 加载javascript代码片段
import javascriptSnippetsUrl from 'ace-builds/src-min-noconflict/snippets/javascript?url'
ace.config.setModuleUrl('ace/snippets/javascript', javascriptSnippetsUrl)

// 加载json代码片段
import jsonSnippetsUrl from 'ace-builds/src-min-noconflict/snippets/json?url'
ace.config.setModuleUrl('ace/snippets/json', jsonSnippetsUrl)

// 加载css代码片段
import cssSnippetsUrl from 'ace-builds/src-min-noconflict/snippets/css?url'
ace.config.setModuleUrl('ace/snippets/css', cssSnippetsUrl)

// 加载lua代码片段
import luaSnippetsUrl from 'ace-builds/src-min-noconflict/snippets/lua?url'
ace.config.setModuleUrl('ace/snippets/lua', luaSnippetsUrl)

// 加载查找功能
import extSearchBox from 'ace-builds/src-min-noconflict/ext-searchbox?url'
ace.config.setModuleUrl('ace/ext/searchbox', extSearchBox)

// 加载语言工具
import 'ace-builds/src-min-noconflict/ext-language_tools'
ace.require('ace/ext/language_tools')

export default {
  name: 'CodeEditor',
  props: {
    modelValue: {
      type: String,
      default: ''
      //required: true
    },
    readonly: {
      type: Boolean,
      default: false
    },
    mode: {
      type: String,
      default: 'javascript'
    },
    userWorker: {
      //是否开启语法检查，默认开启
      type: Boolean,
      default: true
    },
    height: {
      type: Number,
      default: 460
    }
  },
  emits: ['update:modelValue'],
  data() {
    return {
      aceEditor: null,
      themePath: 'ace/theme/sqlserver',
      modePath: 'ace/mode/javascript',
      codeValue: this.modelValue
    }
  },
  watch: {
    //
  },
  mounted() {
    this.addAutoCompletion(ace) //添加自定义代码提示！！

    // let lines = Math.floor(this.height / 14)
    this.aceEditor = ace.edit(this.$refs.ace, {
      // maxLines: lines, // 最大行数，超过会自动出现滚动条
      // minLines: lines, // 最小行数，还未到最大行数时，编辑器会自动伸缩大小
      fontSize: 15, // 编辑器内字体大小
      theme: this.themePath, // 默认设置的主题
      mode: this.modePath, // 默认设置的语言模式
      tabSize: 4, // 制表符设置为4个空格大小
      readOnly: this.readonly,
      highlightActiveLine: true,
      value: this.codeValue,
      wrap: true,
      showPrintMargin: false
    })

    this.aceEditor.setOptions({
      enableBasicAutocompletion: true,
      enableSnippets: true, // 设置代码片段提示
      enableLiveAutocompletion: true // 设置自动提示
    })

    if (this.mode === 'json') {
      this.setJsonMode()
    } else if (this.mode === 'css') {
      this.setCssMode()
    } else if (this.mode === 'lua') {
      this.setLuaMode()
    } else {
      this.setJsMode()
    }

    if (!this.userWorker) {
      this.aceEditor.getSession().setUseWorker(false)
    }

    //编辑时同步数据
    this.aceEditor.getSession().on('change', () => {
      this.$emit('update:modelValue', this.aceEditor.getValue())
    })
  },
  methods: {
    addAutoCompletion(ace) {
      let acData = [
        { meta: 'VForm API', caption: 'getWidgetRef', value: 'getWidgetRef()', score: 1 },
        { meta: 'VForm API', caption: 'getFormRef', value: 'getFormRef()', score: 1 }
        //TODO: 待补充！！
      ]
      let langTools = ace.require('ace/ext/language_tools')
      langTools.addCompleter({
        getCompletions: function (editor, session, pos, prefix, callback) {
          if (prefix.length === 0) {
            return callback(null, [])
          } else {
            return callback(null, acData)
          }
        }
      })
    },

    setJsonMode() {
      this.aceEditor.getSession().setMode('ace/mode/json')
    },

    setCssMode() {
      this.aceEditor.getSession().setMode('ace/mode/css')
    },

    setLuaMode() {
      this.aceEditor.getSession().setMode('ace/mode/lua')
    },

    setJsMode() {
      this.aceEditor.getSession().setMode('ace/mode/javascript')
    },

    getEditorAnnotations() {
      return this.aceEditor.getSession().getAnnotations()
    },

    setValue(newValue) {
      this.aceEditor.getSession().setValue(newValue)
    }
  }
}
</script>

<style lang="scss" scoped>
.ace-editor {
  min-height: 400px;
  height: 700px;
}
</style>
